﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace client
{
    public partial class Gra : Form
    {
        int piatki = 1;
        int czworki = 1;
        int trojki = 3;
        int dwojki = 2;
        int wybranyRodzaj;
        XYButton nacelowany;
        List<Statek> MojeStatki;

        #region Blocki i Unblocki

        private void blockAllMyFields()
        {
            foreach (System.Windows.Forms.Control element in Controls)
            {
                if (element.Name.Substring(0, 2) == "ja")
                {
                    element.Enabled = false;
                }
            }
        }

        private void unblockAllMyFields()
        {
            foreach (System.Windows.Forms.Control element in Controls)
            {
                if (element.Name.Substring(0, 2) == "ja")
                {
                    element.Enabled = true;
                }
            }
        }

        private void blockAllHisFields()
        {
            foreach (System.Windows.Forms.Control element in Controls)
            {
                if (element.Name.Substring(0, 2) == "ty")
                {
                    element.Enabled = false;
                }
            }
        }

        private void unblockAllHisFields()
        {
            foreach (System.Windows.Forms.Control element in Controls)
            {
                if (element.Name.Substring(0, 2) == "ty")
                {
                    element.Enabled = true;
                }
            }
        }

        #endregion

        public Gra()
        {
            wybranyRodzaj = 0;
            MojeStatki = new List<Statek>();
            InitializeComponent();
        }

        private bool czyPrzegralem()
        {
            foreach (Statek ship in MojeStatki)
            {
                if (ship.czyZywy())
                    return false;
            }
            return true;
        }

        private void ZablokujRozmieszczanie()
        {
            blockAllMyFields();
            startButton.Enabled = false;
            Program.buforek[0] = 247;
            Program.Serwer.Send(Program.buforek, 1, 0);
            MessageBox.Show("Oczekiwanie na przeciwnika!");
            Program.buforek[0] = 0;
            while (Program.buforek[0] != 247)
            {
                try
                {
                    Program.Serwer.Receive(Program.buforek, 1, 0);
                }
                catch (Exception exc)
                { }
            };
            unblockAllHisFields();
            fireButton.Enabled = true;
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Wyslanie potwierdzenia rozmieszczenia floty!");
            ZablokujRozmieszczanie();
        }

        private void fireButton_Click(object sender, EventArgs e)
        {
            if (nacelowany == null)
            {
                MessageBox.Show("Wyceluj swoje dziala!");
                return;
            }

            blockAllHisFields();
            fireButton.Enabled = false;

            byte cel = (byte)(nacelowany.x * 8 + nacelowany.y);
            Program.buforek[0] = cel;
            Program.Serwer.Send(Program.buforek, 1, 0);

            MessageBox.Show("Oczekiwanie na ruch przeciwnika!");
            while (true)
            {
                Program.Serwer.Receive(Program.buforek);
                if (Program.buforek[0] < 70)
                {
                    byte odpowiedz = zestrzel(Program.buforek[0]);
                    if (odpowiedz == 199)
                    {
                        if (czyPrzegralem())
                        {
                            odpowiedz = 171;
                        }
                    }
                    Program.buforek[0] = odpowiedz;
                    Program.Serwer.Send(Program.buforek, 1, 0);
                    Program.Serwer.Receive(Program.buforek, 1, 0);
                    if (Program.buforek[0] == 174)
                        WYGRANA();
                    else
                    {
                        switch (Program.buforek[0])
                        {
                            case 186:
                                nacelowany.BackColor = Color.PaleTurquoise;
                                break;
                            case 213:
                                nacelowany.BackColor = Color.DarkOrange;
                                break;
                            case 199:
                                nacelowany.BackColor = Color.Red;
                                break;
                            default:
                                nacelowany.BackColor = Color.Blue;
                                break;
                        }
                    }
                    break;
                }
            }

            nacelowany = null;
            if (czyPrzegralem())
            {
                MessageBox.Show("Przegrales!");
                Program.RozlaczSerwer();
                this.Close();
            }
            unblockAllHisFields();
        }

        private void Gra_FormClosing(object sender, FormClosingEventArgs e)
        {
            Program.log.Enabled = true;
            Program.log.Visible = true;
        }

        #region Rozmieszczanie statków

        private void verOrHor_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (wybranyRodzaj != 0)
                unblockAllMyFields();
        }

        private void ja_Click(object sender, EventArgs e)
        {
            if (wybranyRodzaj == 0)
                return;
            bool bul = false;
            if (verOrHor.SelectedIndex == 0) //POZIOM
            {
                if (((XYButton)sender).y <= 8 - wybranyRodzaj)
                {
                    List<XYButton> fields = sprawdzonkoPol(0, 1, (XYButton)sender, wybranyRodzaj);
                    if (fields.Count == wybranyRodzaj)
                    {
                        MojeStatki.Add(new Statek(wybranyRodzaj, fields));
                        bul = true;
                    }
                }
            }
            else //PION
            {
                if (((XYButton)sender).x <= 8 - wybranyRodzaj)
                {
                    List<XYButton> fields = sprawdzonkoPol(1, 0, (XYButton)sender, wybranyRodzaj);
                    if (fields.Count == wybranyRodzaj)
                    {
                        MojeStatki.Add(new Statek(wybranyRodzaj, fields));
                        bul = true;
                    }
                }
            }
            if (bul)
            {
                switch (wybranyRodzaj)
                {
                    case 2:
                        dwojki--;
                        if (dwojki == 0)
                        {
                            Deploy2.Enabled = false;
                            aktywator2.Enabled = false;
                            aktywator2.Checked = false;
                            wybranyRodzaj = 0;
                        }
                        licznik2.Text = dwojki.ToString();
                        break;
                    case 3:
                        trojki--;
                        if (trojki == 0)
                        {
                            Deploy3.Enabled = false;
                            aktywator3.Enabled = false;
                            aktywator3.Checked = false;
                            wybranyRodzaj = 0;
                        }
                        licznik3.Text = trojki.ToString();
                        break;
                    case 4:
                        czworki--;
                        if (czworki == 0)
                        {
                            Deploy4.Enabled = false;
                            aktywator4.Enabled = false;
                            aktywator4.Checked = false;
                            wybranyRodzaj = 0;
                        }
                        licznik4.Text = czworki.ToString();
                        break;
                    case 5:
                        piatki--;
                        if (piatki == 0)
                        {
                            Deploy5.Enabled = false;
                            aktywator5.Enabled = false;
                            aktywator5.Checked = false;
                            wybranyRodzaj = 0;
                        }
                        licznik5.Text = piatki.ToString();
                        break;
                }
            }
            
            if ((piatki == 0)&&(czworki == 0) && (trojki == 0) && (dwojki == 0))
            {
                startButton.Enabled=true;
            }
        }

        private List<XYButton> sprawdzonkoPol(int ver, int hor, XYButton next, int howManyMore)
        {
            bool test = next.czyZajety();
            if (howManyMore == 1)
            {
                List<XYButton> newList = new List<XYButton>();
                if (!test)
                    newList.Add(next);
                return newList;
            } else {
                List<XYButton> nextList = sprawdzonkoPol(ver, hor, dajPole(next.x + ver, next.y + hor), howManyMore - 1);
                if (!test)
                    nextList.Add(next);
                return nextList;
            }
        }

        private XYButton dajPole(int x, int y)
        {
            foreach (System.Windows.Forms.Control element in Controls)
            {
                if (element.Name.Substring(0, 2) == "ja")
                {
                    if ((((XYButton)element).x == x) && (((XYButton)element).y == y))
                        return (XYButton)element;
                }
            }
            return null;
        }

        #region Przyciski wyboru statków

        private void Deploy5_Click(object sender, EventArgs e)
        {
            wybranyRodzaj = 5;
            aktywator2.Checked = false;
            aktywator3.Checked = false;
            aktywator4.Checked = false;
            aktywator5.Checked = true;
            if (verOrHor.SelectedIndex != -1)
                unblockAllMyFields();
        }

        private void Deploy4_Click(object sender, EventArgs e)
        {
            wybranyRodzaj = 4;
            aktywator2.Checked = false;
            aktywator3.Checked = false;
            aktywator4.Checked = true;
            aktywator5.Checked = false;
            if (verOrHor.SelectedIndex != -1)
                unblockAllMyFields();
        }

        private void Deploy3_Click(object sender, EventArgs e)
        {
            wybranyRodzaj = 3;
            aktywator2.Checked = false;
            aktywator3.Checked = true;
            aktywator4.Checked = false;
            aktywator5.Checked = false;
            if (verOrHor.SelectedIndex != -1)
                unblockAllMyFields();
        }

        private void Deploy2_Click(object sender, EventArgs e)
        {
            wybranyRodzaj = 2;
            aktywator2.Checked = true;
            aktywator3.Checked = false;
            aktywator4.Checked = false;
            aktywator5.Checked = false;
            if (verOrHor.SelectedIndex != -1)
                unblockAllMyFields();
        }

        #endregion

        #endregion

        private bool odbiorNagrody()
        {
            try
            {
                byte[] mojLong = new byte[4];
                if (Program.Serwer.Receive(mojLong, 4, 0) != 4)
                {
                    MessageBox.Show("Blad przy odbieraniu dlugosci\n");
                    return false;
                }
                int jeden = System.BitConverter.ToInt32(mojLong,0);
                int dl_pliku = IPAddress.NetworkToHostOrder(jeden);
                int odebrano_razem = 0;
                using (FileStream stream = new FileStream("Nagroda.avi", FileMode.Create))
                {
                    using (BinaryWriter writer = new BinaryWriter(stream))
                    {
                        while (odebrano_razem < dl_pliku)
                        {
                            byte[] bufforNaPlik = new byte[1024];
                            int odebrano = Program.Serwer.Receive(bufforNaPlik);
                            if (odebrano < 0)
                                break;
                            odebrano_razem += odebrano;
                            writer.Write(bufforNaPlik);
                        }
                        writer.Close();
                    }
                }
                if (odebrano_razem != dl_pliku)
                {
                    MessageBox.Show("*** BLAD W ODBIORZE PLIKU ***\n");
                    return false;
                }
                else return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Blad przy pobieraniu pliku nagrody! :(\nWiadomosc: " + ex.ToString());
                return false;
            }
        }

        private void WYGRANA()
        {
            MessageBox.Show("Wygrales!");
            if (odbiorNagrody())
            {
                System.Diagnostics.Process.Start("Nagroda.avi");
            }
            Program.RozlaczSerwer();
            this.Close();
        }

        private byte zestrzel(byte cel)
        {
            byte iks = (byte)(cel/8);
            byte ygrek = (byte)(cel - iks*8);

            XYButton celP = dajPole(iks, ygrek);
            celP.strzal();

            switch (celP.BackColor.ToString())
            {
                case "Color [PaleTurquoise]":
                    return 186;
                case "Color [DarkOrange]":
                    return 213;
                case "Color [Red]":
                    return 199;
                default:
                    return 0;
            }
        }

        //Metoda nacelowuje strzal na pole wroga!
        private void ty_Click(object sender, EventArgs e)
        {
            if (nacelowany != null)
            {
                nacelowany.Enabled = true;
            }

            nacelowany = ((XYButton)sender);
            nacelowany.Enabled = false;
            fireButton.Enabled = true;
        }
    }
}
